package com.songlanyun.modules.order.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jushuitan.api.ApiClient;
import com.jushuitan.api.ApiRequest;
import com.jushuitan.api.ApiResponse;
import com.jushuitan.api.DefaultApiClient;
import com.jushuitan.api.exception.ApiException;
import com.songlanyun.common.enums.*;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.kqUtils.InitQuery;
import com.songlanyun.common.utils.StrUtil;
import com.songlanyun.modules.account.dao.AccountDao;
import com.songlanyun.modules.account.entity.AccountEntity;
import com.songlanyun.modules.account.entity.UserIdentityAssetEntity;
import com.songlanyun.modules.account.model.vo.AccountParentVO;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.account.service.UserIdentityAssetService;
import com.songlanyun.modules.areafeature.service.GoodsAreaFeatureService;
import com.songlanyun.modules.exception.OrderException;
import com.songlanyun.modules.gains.service.ShopOrderGainsService;
import com.songlanyun.modules.goods.entity.Goods;
import com.songlanyun.modules.goods.service.GoodsService;
import com.songlanyun.modules.integralrecord.entity.IntegralRecord;
import com.songlanyun.modules.integralrecord.service.IntegralRecordService;
import com.songlanyun.modules.jst.dao.jstDao;
import com.songlanyun.modules.jst.entiy.JstRecord;
import com.songlanyun.modules.logisticsconfig.entity.LogisticsConfig;
import com.songlanyun.modules.logisticsconfig.service.LogisticsConfigService;
import com.songlanyun.modules.marketing.groupbuy.service.GroupBuyTeamMemberService;
import com.songlanyun.modules.marketing.groupbuy.service.GroupBuyTeamService;
import com.songlanyun.modules.marketing.seckill.service.SeckillActivityGoodsService;
import com.songlanyun.modules.memberbill.service.SaleRefillCardBillService;
import com.songlanyun.modules.message.model.to.MessageTO;
import com.songlanyun.modules.message.service.SendPrivateMessageMsgService;
import com.songlanyun.modules.order.dao.OrderDao;
import com.songlanyun.modules.order.entity.*;
import com.songlanyun.modules.order.service.*;
import com.songlanyun.modules.payorder.entity.PayOrder;
import com.songlanyun.modules.payorder.service.PayOrderService;
import com.songlanyun.modules.publicbenefitmsg.service.PublicBenefitMsgService;
import com.songlanyun.modules.rabbitmq.MqConstant;
import com.songlanyun.modules.rabbitmq.mq.producer.SendOrderOrRightsOrderMsgService;
import com.songlanyun.modules.rabbitmq.service.SendMsgService;
import com.songlanyun.modules.saleconfig.service.SaleConfigService;
import com.songlanyun.modules.servicegoods.entity.ServiceGoods;
import com.songlanyun.modules.servicegoods.service.ServiceGoodsService;
import com.songlanyun.modules.shop.service.ShopService;
import com.songlanyun.modules.singlegoods.model.OrderStockTo;
import com.songlanyun.modules.singlegoods.service.ProductSingleGoodsService;
import com.songlanyun.modules.sysbill.service.SysBillService;
import com.songlanyun.modules.useraddress.entity.UserAddress;
import com.songlanyun.modules.useraddress.service.UserAddressService;
import com.songlanyun.modules.usergains.entity.UserBill;
import com.songlanyun.modules.usergains.service.UserBillService;
import com.songlanyun.modules.usergains.service.UserOrderGainsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;


@Service("orderOperationService")
@Slf4j
public class OrderOperationServiceImpl extends ServiceImpl<OrderDao, Order> implements OrderOperationService {


    @Autowired
    private ShopService shopService;

    @Autowired
    private ServiceGoodsService serviceGoodsService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private PayOrderService payOrderService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private ChildOrderService childOrderService;

    @Autowired
    private ProductSingleGoodsService productSingleGoodsService;

    @Autowired
    private LogisticsConfigService logisticsConfigService;

    @Autowired
    private UserIdentityAssetService userIdentityAssetService;

    @Autowired
    private OrderReceiptService orderReceiptService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private UserAddressService userAddressService;

    @Autowired
    private SaleRefillCardBillService saleRefillCardBillService;

    @Autowired
    private SysBillService sysBillService;

    @Autowired
    private GroupBuyTeamMemberService groupBuyTeamMemberService;

    @Autowired
    private GroupBuyTeamService groupBuyTeamService;

    @Autowired
    private SeckillActivityGoodsService seckillActivityGoodsService;

    @Autowired
    private ShopOrderGainsService shopOrderGainsService;

    @Autowired
    SendMsgService sendMsgService;

    @Autowired
    SaleConfigService saleConfigService;

    @Autowired
    SaleServiceGoodsCardService saleServiceGoodsCardService;

    @Autowired
    IntegralRecordService integralRecordService;
    @Autowired
    GoodsAreaFeatureService goodsAreaFeatureService;


    @Autowired
    PublicBenefitMsgService publicBenefitMsgService;

    @Autowired
    UserBillService userBillService;

    @Autowired
    private jstDao jstDao;

    @Resource
    private SendOrderOrRightsOrderMsgService sendOrderOrRightsOrderMsgService;

    @Autowired
    private SendPrivateMessageMsgService sendPrivateMessageMsgService;




    /**
     * 取消支付
     *
     * @param userId
     * @param payOrderId
     * @return
     */
    @Transactional
    @Override
    public PayOrder cancelPay(Long userId, Long payOrderId) {

        PayOrder payOrder = payOrderService.getByUserIdAndId(userId, payOrderId, true);

        if (payOrder.getClose()) {
            //支付订单已关闭,不能取消支付
            throw new RRException(OrderException.PAY_ORDER_CLOSED);
        }

        if (payOrder.isFactPaySuccess()) {
            //支付订单已成功支付,不取消支付
            throw new RRException(OrderException.PAY_SUCCESS_NOT_CLOSE);
        }
        cancel(payOrder, OrderConstant.CloseMode.USER_CANCEL, GoodsConstant.InStockType.CANCEL_ORDER);


        return payOrder;
    }


    /**
     * 支付过期取消订单
     *
     * @param payOrderId
     * @return
     */
    @Transactional
    @Override
    public Boolean payExpireCancel(Long payOrderId) {
        PayOrder payOrder = payOrderService.getById(payOrderId);
        if (payOrder == null) {
            throw new RRException(OrderException.PAY_ORDER_NOT_EXISTS);
        }

        // 快钱支付验证
        if (this.kqOrderQuery(payOrder)) {
            // 判定快钱支付成功后,重新查询订单
            // kqOrderQuery方法完成支付成功逻辑
            return true;
        }

        if (payOrder.getClose()) {
            //支付订单已关闭,不能取消支付
            throw new RRException(OrderException.PAY_ORDER_CLOSED);
        }

        if (payOrder.isFactPaySuccess()) {
            //支付订单已成功支付,不取消支付
            throw new RRException(OrderException.PAY_SUCCESS_NOT_CLOSE);
        }

        payOrder.setPaymentStatus(OrderConstant.PaymentStatus.EXPIRE);
        cancel(payOrder, OrderConstant.CloseMode.PAY_EXPIRE, GoodsConstant.InStockType.PAY_EXPIRE);
        return true;
    }

    public boolean kqOrderQuery(PayOrder payOrder) {

        boolean paySuccess = false;

        if (payOrder.isFactPaySuccess()) {
            log.info("支付过期取消订单-该订单pay_code:{} ,前置校验订单支付成功,直接success", payOrder.getCode());
            paySuccess = true;
            return paySuccess;
        }

        log.info("支付过期取消订单-该订单pay_code:{} ,前置校验订单支付失败,进入支付查询逻辑", payOrder.getCode());

        JSONObject kqOrderQueryJs = new JSONObject();
        try {
            Map<String, Object> map = InitQuery.gateWayInitQuery(payOrder.getCode());

            kqOrderQueryJs = JSONObject.parseObject(JSONObject.toJSONString(map));
            log.info("快钱订单查询:{}", kqOrderQueryJs.toJSONString());

            if ("1".equals(kqOrderQueryJs.getString("resultCode"))) {
                // 只有在请求成功以及,订单支付成功后,才触发paySuccess的变更
                if ("S".equals(kqOrderQueryJs.getString("txnFlg"))) {
                    // 订单支付成功
                    paySuccess = true;
                    log.info("支付过期取消订单-该订单pay_code:{} ,为快钱订单且支付成功", payOrder.getCode());

                }
            }

        } catch (Exception e) {
            // 非快钱订单/调用接口失败,直接返回
            paySuccess = false;
            log.info("支付过期取消订单-该订单pay_code:{} ,非快钱订单/调用接口失败,不进行快钱订单验证", payOrder.getCode());
            return paySuccess;
        }

        try {
            if (paySuccess) {
                // 该订单为快钱订单且支付成功
                String txnType = kqOrderQueryJs.getString("txnType");
                // 本地订单号
                String outOrderNo = kqOrderQueryJs.getString("externalTraceNo");
                // 三方订单号
                String innerOrderNo = kqOrderQueryJs.getString("idBizCtrl");
                // 总金额
                BigDecimal money = kqOrderQueryJs.getBigDecimal("amt");

                //处理支付逻辑
                log.info("支付过期取消订单-该订单pay_code:{} 支付逻辑运行中", payOrder.getCode());
                payOrder = payOrderService.paymentHandle(outOrderNo, innerOrderNo, money, OrderConstant.PayMode.QUICK_PAY);
                log.info("支付过期取消订单-该订单pay_code:{} 支付逻辑运行完成", payOrder.getCode());
                //消费订单  支付成功发送消息
                if (!payOrder.getOrderType().equals(OrderConstant.OrderType.REFILL_ORDER)) {
                    sendOrderOrRightsOrderMsgService.paySuccessSendMsg(payOrder);
                } else {
                    //发送充值商品支付成功站内消息
                    sendPrivateMessageMsgService.send(new MessageTO(PrivateMessageConstant.MessageType.PAY_MESSAGE,
                            PrivateMessageConstant.ModelType.REFILL_PAY_SUCCESS, payOrder.getId()));
                }

            }
        } catch (Exception e) {
            // 非快钱订单/调用接口失败,直接返回
            paySuccess = false;
            log.info("支付过期取消订单-该订单pay_code:{} ,为快钱订单,支付逻辑运行失败", payOrder.getCode());
            return paySuccess;
        }

        return paySuccess;
    }

    /**
     * 第三方回调支付需要使用的服务
     *
     * @param payOrder
     * @return
     */
    @Override
    public PayOrder pay(PayOrder payOrder) {

        payOrder = paySuccess(payOrder, payOrder.getPayMode());

        /**
         * 入系统账单---------------------------------------------------
         */
        if (!OrderConstant.PayMode.BALANCE.equals(payOrder.getPayMode())) {
            if (payOrder.getTotalAmount().compareTo(BigDecimal.ZERO) > 0) {
                String mobile = accountService.getMobileByUserId(payOrder.getUserId());
                sysBillService.saveIncomeBill(payOrder.getPayMode(), BillConstant.BillType.BUY_GOODS, payOrder.getTotalAmount(),
                        payOrder.getCode(), payOrder.getThirdPayCode(), mobile);
            }
        }

        return payOrder;
    }

    /**
     * 第三方回调支付需要使用的服务
     *
     * @param payOrder
     * @return
     */
    @Override
    public PayOrder payFail(PayOrder payOrder) {
        payOrder = payFailSuccess(payOrder, payOrder.getPayMode());
        return payOrder;
    }


    /**
     * 用余额支付
     *
     * @param payOrderId
     * @return
     */
    @Transactional
    @Override
    public PayOrder balancePay(Long userId, Long payOrderId) {

        PayOrder payOrder = payOrderService.getByUserIdAndId(userId, payOrderId, true);
        validatePayOrder(payOrder);
        if (payOrder.getTotalAmount().compareTo(BigDecimal.ZERO) == 0) {
            throw new RRException(OrderException.MONEY_NO_ZERO);
        }

        saleRefillCardBillService.subBalance(payOrder.getUserId(), payOrder.getTotalAmount(), payOrder.getCode(), BillConstant.OuterMode.CONSUME);
        if (payOrder.getPointGoods()) {
            return paySuccess(payOrder, OrderConstant.PayMode.POINT_BALANCE);
        } else {
            //支付成功之后的订单处理
            return paySuccess(payOrder, OrderConstant.PayMode.BALANCE);
        }

    }

    @Override
    public PayOrder voucherPay(Long userId, Long payOrderId) {
        PayOrder payOrder = payOrderService.getByUserIdAndId(userId, payOrderId, true);
        validatePayOrder(payOrder);
        if (payOrder.getTotalAmount().compareTo(BigDecimal.ZERO) == 0) {
            throw new RRException(OrderException.MONEY_NO_ZERO);
        }

//        saleRefillCardBillService.subBalance(payOrder.getUserId(), payOrder.getTotalAmount(), payOrder.getCode(), BillConstant.OuterMode.CONSUME);
        saleRefillCardBillService.subVoucher(payOrder.getUserId(), payOrder.getTotalAmount(), payOrder.getCode(), BillConstant.OuterMode.CONSUME);
        if (payOrder.getPointGoods()) {
            return paySuccess(payOrder, OrderConstant.PayMode.POINT_BALANCE);
        } else {
            //支付成功之后的订单处理
            return paySuccess(payOrder, OrderConstant.PayMode.VOUCHER_PAY);
        }
    }

    @Autowired
    private UserOrderGainsService userOrderGainsService;
    /**
     * 修改订单的收货地址
     *
     * @param userId
     * @param orderId
     * @param userAddressId
     * @return
     */
    @Override
    public OrderReceipt updateReceipt(Long userId, Long orderId, Long userAddressId) {

        Order order = orderService.loadByUserIdAndId(userId, orderId, true);
        if (!OrderConstant.ShipmentMode.EXPRESS.equals(order.getShipmentMode())) {
            throw new RRException(OrderException.NOT_EXPRESS_ORDER);
        }
        if (OrderConstant.ShipStatus.ALREADY_SHIP.equals(order.getShipStatus())) {
            throw new RRException(OrderException.SHIP_NOT_UPDATE_EXPRESS);
        }

        OrderReceipt obj = editReceipt(order, userAddressId);

        return obj;
    }


    /**
     * 修改订单的收货地址（内部调用）
     *
     * @param order
     * @param userAddressId
     * @return
     */
    private OrderReceipt editReceipt(Order order, Long userAddressId) {
        UserAddress userAddress = userAddressService.getByUserIdAndId(order.getUserId(), userAddressId);
        OrderReceipt receipt = order.loadOrderReceipt();
        if (userAddress != null) {

            Long id = receipt.getId();
            BeanUtils.copyProperties(userAddress, receipt);
            receipt.setReceiver(userAddress.getName());
            receipt.setMobile(userAddress.getPhone());
            receipt.setId(id);
            receipt.setOrderId(order.getId());
            orderReceiptService.modify(receipt);
        }
        return receipt;
    }

    /**
     * 修改支付订单的收货地址
     *
     * @param userId
     * @param payOrderId
     * @param userAddressId
     */
    @Transactional
    @Override
    public void updateReceiptForPayOrder(Long userId, Long payOrderId, Long userAddressId) {
        PayOrder payOrder = payOrderService.getByUserIdAndId(userId, payOrderId, true);

        List<Order> orders = orderService.loadByPayOrderId(payOrder.getId());
        orders.forEach(order -> {
            editReceipt(order, userAddressId);
        });
    }


    /**
     * 验证支付订单的状态
     *
     * @param payOrder
     */
    private void validatePayOrder(PayOrder payOrder) {
        if (payOrder.getClose()) {
            //支付订单已关闭,不能取消支付
            throw new RRException(OrderException.PAY_ORDER_CLOSED_NOT_PAY);
        }

        if (payOrder.isFactPaySuccess()) {
            //支付订单已成功支付,不取消支付
            throw new RRException(OrderException.NOT_REPEAT_PAY);
        }

        if (payOrder.getExpiredPayTime() < System.currentTimeMillis()) {
            //支付已过期
            throw new RRException(OrderException.PAY_EXPIRED);
        }


    }


    /**
     * 支付成功之后的订单处理
     *
     * @param payOrder
     * @param payMode
     * @return
     */
    private PayOrder paySuccess(PayOrder payOrder, OrderConstant.PayMode payMode) {
        /**
         * 保存支付订单的状态
         */
        payOrder.setPaymentStatus(OrderConstant.PaymentStatus.SUCCESS);
        payOrder.setPayTime(System.currentTimeMillis());
        payOrder.setPayMode(payMode);
        payOrder.setClose(false);
        payOrder.setCloseMode(OrderConstant.CloseMode.NO);
        payOrderService.modify(payOrder);

        /**
         * 更新支付订单所关联的业务订单的状态
         */
        switch (payOrder.getOrderType()) {
            case SALE_ORDER:
                payOrder = commonGoodsPaySuccess(payOrder);
                payOrderService.uploadOrder(payOrder);
                break;
            case SERVICE_ORDER:
                payOrder = serviceGoodsPaySuccess(payOrder);
                break;
            default:
                throw new RRException("订单支付类型不正确");
        }

        //更新用户的个人业绩
        AccountEntity user = accountService.getUserById(payOrder.getUserId(), true);
        accountDao.updateUserPersonalPerformance(user.getId(), user.getPersonalPerformance().add(payOrder.getTotalAmount()));
        sendMsgService.sendCommon(MqConstant.UserUpgradeConstant.USER_UPGRADE_EXCHANGE,
                MqConstant.UserUpgradeConstant.USER_UPGRADE_ROUTER
                , user.getId().toString());

        return payOrder;
    }

    /**
     * 支付成功之后的订单处理
     *
     * @param payOrder
     * @param payMode
     * @return
     */
    private PayOrder payFailSuccess(PayOrder payOrder, OrderConstant.PayMode payMode) {
        /**
         * 保存支付订单的状态
         */
        payOrder.setPaymentStatus(OrderConstant.PaymentStatus.FAIL);
        payOrder.setPayTime(System.currentTimeMillis());
        payOrder.setPayMode(payMode);
        payOrder.setClose(true);
        payOrder.setCloseMode(OrderConstant.CloseMode.THIRD_PAY_FAIL);
        payOrderService.modify(payOrder);

        /**
         * 更新支付订单所关联的业务订单的状态
         */
        switch (payOrder.getOrderType()) {
            case SALE_ORDER:
                payOrder = commonGoodsPayFailSuccess(payOrder);
                break;
            case SERVICE_ORDER:
                payOrder = serviceGoodsPayFailSuccess(payOrder);
                break;
            default:
                throw new RRException("订单支付类型不正确");
        }

        return payOrder;
    }

    /**
     * 普通支付订单支付成功
     *
     * @param payOrder
     * @return
     */
    private PayOrder commonGoodsPaySuccess(PayOrder payOrder) {

        //用户团队业绩，个人业绩记录
        List<AccountParentVO> vos = accountService.getAllParentUser(payOrder.getUserId());   //获取上级用户
        for (AccountParentVO vo : vos) {
            AccountEntity user1 = accountService.getUserById(vo.getId(), true);
            user1.setTeamPerformance(user1.getTeamPerformance().add(payOrder.getTotalAmount()));
            accountService.updateById(user1);
            System.err.println("执行结果团队"+accountService.updateById(user1));
        }
        List<Order> orders = orderService.loadByPayOrderId(payOrder.getId());
        orders.forEach(order -> {
            //主订单
            order.setTransactionStatus(OrderConstant.TransactionStatus.WAIT_SHIP);
            order.setPaymentStatus(OrderConstant.PaymentStatus.SUCCESS);
            order.setPayTime(payOrder.getPayTime());
            order.setPayMode(payOrder.getPayMode());
            order.setCloseTime(0L);
            order.setEnd(false);
            order.setCloseMode(OrderConstant.CloseMode.NO);
            long autoStockUpTimestamp = 0L;
            if (OrderConstant.ShipmentMode.PICK_UP.equals(order.getShipmentMode())) {
                //如果是自提订单，并且开启了自动备货，就要计算自动备货的时间
                LogisticsConfig logisticsConfig = logisticsConfigService.getLogisticsConfig(order.getShopId());
                if (logisticsConfig != null && logisticsConfig.getAutoStock()) {
                    autoStockUpTimestamp = logisticsConfig.getAutoStockUpTimestamp(System.currentTimeMillis());
                    order.setAutoStockUpLastTime(autoStockUpTimestamp);
                }
            }
            orderService.modify(order);



            /**
             * 更主业务订单订单中的所有子订单的状态
             */
            //聚水谭订单生成
            JSONArray itemArray = new JSONArray();

            Map<Long, Integer> goodsNums = new HashMap<>();
            List<ChildOrder> childOrderList = order.getChildOrderList(true);
            for (ChildOrder child : childOrderList) {
                child.setPaymentStatus(OrderConstant.PaymentStatus.SUCCESS);
                child.setTransactionStatus(OrderConstant.TransactionStatus.WAIT_SHIP);
                child.setEnd(false);
                childOrderService.modify(child);

                if (goodsNums.containsKey(child.getGoodsId())) {
                    goodsNums.put(child.getGoodsId(), goodsNums.get(child.getGoodsId()) + child.getNumber());
                } else {
                    goodsNums.put(child.getGoodsId(), child.getNumber());
                }

//                if (order.getTotalPoint().compareTo(BigDecimal.ZERO) == 0 && order.getTotalAmount().compareTo(BigDecimal.ZERO) == 0) {
//                    //发送消息
//                    publicBenefitMsgService.sendMsg(
//                            PublicBenefitMsgTO.builder()
//                                    .type(DonationConstant.MsgType.BUY)
//                                    .userId(child.getUserId())
//                                    .msgBody(
//                                            BuyMsg.builder().goodsCover(child.getGoodsImg())
//                                                    .goodsAmount(BigDecimal.ZERO)
//                                                    .goodsTitle(child.getGoodsTitle())
//                                                    .goodsId(child.getGoodsId())
//                                                    .modelType(DonationConstant.BuyMsgType.FREE_GOODS)
//                                                    .build()
//                                    )
//                                    .content(String.format("领取了公益免费产品“%s”", child.getGoodsTitle()))
//                                    .build()
//                    );
//                }


                if(child.getTotalConsumptionValue().compareTo(BigDecimal.ZERO)>0)
                {


                    userBillService.inUserBill(child.getUserId(),child.getOrderCode(),child.getConsumptionValue(),UserBillConstant.BillType.INCOME,UserBillConstant.InnerMode.BUY_INCOME);


//                    if(GoodsConstant.AreaFeature.ACTIVATING.equals(child.getAreaFeature())) {
//                        userBillService.inBill(child.getUserId(),
//                                String.format("购买了\" %s\"", StrUtil.truncation(child.getGoodsTitle(), 10)),
//                                UserBillConstant.InnerMode.BUY_INCOME,
//                                child.getTotalConsumptionValue(),
//                                child.getOrderCode(),"系统");
////                        JSONObject jsonData = getJsonData(child, order);
////                        itemArray.add(jsonData);
//                    }
                    //兑换区商品聚水潭发货
//                    if(child.getGoodsCategoryId() == (long)GoodsConstant.AreaFeature.EXCHANGING.getCode()) {
////                        AccountEntity account = accountService.getUserById(child.getUserId(), true);
////                        if (account.getLastActivatingTime() != null){
////                            account.setActivating(true);
////                            account.setLastActivatingTime(new Date());
////                            accountService.modify(account);
////                        }
//                        //增加贡献值
//                        //修改会员可贡献值
//                        UserIdentityAssetEntity userIdentity = userIdentityAssetService.updateCommissionAble(child.getUserId(), child.getTotalConsumptionValue(), true);
//                        UserBill userBill = new UserBill();
//                        userBill.setUserId(child.getUserId());
//                        userBill.setBillType(UserBillConstant.BillType.INCOME);//入账
//                        userBill.setInnerMode(UserBillConstant.InnerMode.BUY_INCOME);//入账方式
//                        userBill.setRemark("兑换券兑换商品所得");//备注
//                        userBill.setCode(child.getOrderCode());//单号
//                        userBill.setEntryBefore(userIdentity.getCommissionAble().subtract(child.getTotalConsumptionValue()));//入帐前的可提现佣金
//                        userBill.setEntryAfter(userIdentity.getCommissionAble());//入帐后的可提现佣金
//                        userBill.setEntryValue(child.getTotalConsumptionValue());
//                        userBill.setOperator("系统");
//                        userBillService.save(userBill);
//                        JSONObject jsonData = getJsonData(child, order);
//                        itemArray.add(jsonData);
//                    }

                }


            }

            /**
             * 商品销量增加
             */
            goodsNums.entrySet().stream().forEach(o -> {
                Goods goods = goodsService.getById(o.getKey(), false);
                if (goods != null) {
                    goods.incSaleNum(o.getValue());
                    goodsService.modify(goods);
                }
            });

            //如果是评团
            if (order.getMarketingType() == 2) {
                groupBuyTeamService.paySuccess(order);
            }
            else
            {
                //计算商家与会员分润所得
                if ((!order.getExchange()) && order.getTotalAmount().compareTo(BigDecimal.ZERO) > 0) {
                    shopOrderGainsService.initCreate(order);
                }
            }

            if (itemArray.size() > 0){
                //收货地址
                OrderReceipt orderReceipt = orderReceiptService.loadOrderReceiptBy(order.getId());
//                UserAddress userAddress = userAddressService.getDefaultByUserId(payOrder.getUserId());
                //订单总信息
                JSONObject jsonObject = commonParameter(order, itemArray, orderReceipt,payOrder);

                JSONArray result = new JSONArray();
                result.add(jsonObject);
                String biz = result.toJSONString();
                ApiResponse response = send(biz);
                String body = response.getBody();
                //返回的状态信息值
                JSONObject jsonObject1 = JSONObject.parseObject(body);
                //返回订单值
                if (!jsonObject1.get("code").toString().equals("0")){
                    JstRecord jstRecord = new JstRecord();
                    jstRecord.setCode(jsonObject1.get("code").toString());
                    jstRecord.setCreateTime(new Date());
                    jstRecord.setMsg(jsonObject1.get("msg").toString());
                    jstRecord.setOrderId(order.getId());
                    jstDao.insert(jstRecord);
                    System.out.println("订单：" + order.getId() + "推送失败");
                }else {
                    JSONObject jsonObject2 = jsonObject1.getJSONObject("data").getJSONArray("datas").getJSONObject(0);
                    JstRecord jstRecord = new JstRecord();
                    jstRecord.setCode(jsonObject1.get("code").toString());
                    jstRecord.setCreateTime(new Date());
                    jstRecord.setMsg(jsonObject1.get("msg").toString());
                    jstRecord.setOrderId(order.getId());
                    jstRecord.setOId(jsonObject2.get("o_id").toString());
                    jstRecord.setSoId(jsonObject2.get("so_id").toString());
                    jstDao.insert(jstRecord);
                    System.out.println("订单：" + order.getId() + "推送成功");
                }
            }


//            if (order.getServiceSystemGoods()) {
//                accountService.updateServiceSystem(order.getUserId(), order.getServicePackageArea());
//            }


        });

        return payOrder;
    }

    private JSONObject getJsonData(ChildOrder childOrder,Order order){
        //https://openweb.jushuitan.com/dev-doc?docType=4&docId=18#请求示例

        Goods goods = goodsService.getById(childOrder.getGoodsId());
        JSONObject itemJson = new JSONObject();   //商品明细
        itemJson.put("sku_id",goods.getSpuCode());    //商品编码 457325851058556
        itemJson.put("shop_sku_id","123");    //商品编码  id
        itemJson.put("amount",childOrder.getTotalRealPrice());    //商品金额  两位小数
        itemJson.put("base_price",childOrder.getTotalRealPrice());    //商品原价  两位小数
        itemJson.put("name",goods.getTitle());    //商品名称
        itemJson.put("outer_oi_id",childOrder.getOrderId().toString());    //商品子订单id
        itemJson.put("qty",childOrder.getNumber());
  //商品数量
        return itemJson;
    }

    private JSONObject commonParameter(Order order,JSONArray itemArray,OrderReceipt orderReceipt,PayOrder payOrder) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        JSONObject jsonObject = new JSONObject();

        jsonObject.put("shop_id",15951789);    //店铺id
        jsonObject.put("so_id",order.getOrderCode());     //自研商城系统订单号,长度<=50 唯一值
        jsonObject.put("order_date",sdf.format(new Date()));  //订单日期
        jsonObject.put("shop_status","WAIT_SELLER_SEND_GOODS");   //商城订单状态
        jsonObject.put("wms_co_id",13775363);   //一链金服云仓  发货仓编号  固定
        jsonObject.put("shop_buyer_id",orderReceipt.getReceiver());   //买家账号  id
        jsonObject.put("receiver_state",orderReceipt.getProvinceName());   //省
        jsonObject.put("receiver_city",orderReceipt.getCityName());    //市
        jsonObject.put("receiver_district",orderReceipt.getAreaName());   //区
        jsonObject.put("receiver_address",orderReceipt.getAddress());    //详细地址
        jsonObject.put("receiver_name",orderReceipt.getReceiver());    //收货人姓名
        jsonObject.put("receiver_phone",orderReceipt.getMobile());    //收货人电话
        jsonObject.put("pay_amount",order.getGoodsAmount());    //应付金额  小数两位 TODO:需要计算
        jsonObject.put("freight",0);    //运费
        JSONObject payJson = new JSONObject();    //支付信息
        payJson.put("outer_pay_id",order.getPayOrderCode());    //支付单号
        payJson.put("pay_date",sdf.format(new Date()));    //支付日期
        payJson.put("payment",payOrder.getPayMode().getMsg());    //支付方式
        payJson.put("seller_account",payOrder.getCode());    //支付账号
        payJson.put("buyer_account",payOrder.getUserId().toString());    //买家账号
        payJson.put("amount",payOrder.getTotalAmount());    //支付金额  两位小数
        jsonObject.put("pay",payJson);
        jsonObject.put("items",itemArray);
        return jsonObject;
    }

    //聚水潭请求
    private ApiResponse send(String bizs){
        // 实例化client
        ApiClient client = new DefaultApiClient();
        // 设置超时时间
//        ((DefaultApiClient)client).setReadTimeout(3000);
//        ((DefaultApiClient)client).setConnectTimeout(2000);
        // 替换为POP分配给应用的app_key,app_secret,accessToken等
        String url = "https://openapi.jushuitan.com/open/jushuitan/orders/upload";// 示例为测试地址，生产上请替换为正式地址
        String appKey = "d3e46effa5ad41f0a19b17e1066bc863";
        String appSecret = "1704ebbd7c114509941dfafcf2f92483";
        String accessToken = "57bb112e47ac4a0f97f33491163cea59";
//        String biz = "{\"shop_ids\":[],\"page_index\":1,\"page_size\":30}";
        String biz =  bizs;
        // 构建请求对象
        ApiRequest request = new ApiRequest.Builder(url, appKey, appSecret)
                .biz(biz).build();
        System.err.println("biz"+biz);
        ApiResponse response = new ApiResponse();
        // 执行接口调用
        try {
            response = client.execute(request, accessToken);
            System.out.println("is success: " + response.isSuccess());
            System.out.println("body: " + response.getBody());
        } catch (ApiException e) {
            switch (e.getCodeEnum()) {
                case SYS_ERROR:
                    // TODO retry
                    break;
                case PARAM_ERROR:
                    // TODO check param
                    break;
                case SIGN_ERROR:
                    // TODO @see com.jushuitan.api.util.ApiUtil
                    break;
                case CONNECT_ERROR:
                    // TODO check network
                    break;
                case TIME_OUT_ERROR:
                    // TODO check logic or reset readTimeout
                    break;
                case EXECUTE_ERROR:
                    // TODO @see com.jushuitan.api.DefaultApiClient#executeRemote
                    break;
                default:
                    // log
                    break;
            }
        } catch (Exception e) {
            System.out.println("error:"+e);
            // exception handle
        }
        return response;
    }

    private PayOrder commonGoodsPayFailSuccess(PayOrder payOrder) {
        List<Order> orders = orderService.loadByPayOrderId(payOrder.getId());
        orders.forEach(order -> {

            //主订单
            order.setTransactionStatus(OrderConstant.TransactionStatus.CLOSE);
            order.setPaymentStatus(OrderConstant.PaymentStatus.FAIL);
            order.setPayTime(payOrder.getPayTime());
            order.setPayMode(payOrder.getPayMode());
            order.setCloseTime(payOrder.getCloseTime());
            order.setEnd(true);
            order.setCloseMode(OrderConstant.CloseMode.THIRD_PAY_FAIL);
            orderService.modify(order);


            List<ChildOrder> childOrderList = order.getChildOrderList(true);
            for (ChildOrder child : childOrderList) {
                child.setPaymentStatus(OrderConstant.PaymentStatus.FAIL);
                child.setTransactionStatus(OrderConstant.TransactionStatus.CLOSE);
                child.setEnd(true);
                childOrderService.modify(child);
            }
        });

        return payOrder;
    }

    /**
     * 服务订单支付成功
     *
     * @param payOrder
     * @return
     */
    private PayOrder serviceGoodsPaySuccess(PayOrder payOrder) {

        List<Order> orders = orderService.loadByPayOrderId(payOrder.getId());
        orders.forEach(order -> {
            //主订单
            order.setTransactionStatus(OrderConstant.TransactionStatus.WAIT_RECEIPT);
            order.setPaymentStatus(OrderConstant.PaymentStatus.SUCCESS);
            order.setShipStatus(OrderConstant.ShipStatus.ALREADY_SHIP);
            order.setReceiptStatus(OrderConstant.ReceiptStatus.NO);
            order.setPayTime(payOrder.getPayTime());
            order.setPayMode(payOrder.getPayMode());
            order.setCloseTime(0L);
            order.setEnd(false);
            order.setCloseMode(OrderConstant.CloseMode.NO);
            orderService.modify(order);
            /**
             * 更主业务订单订单中的所有子订单的状态
             */
            List<ChildOrder> childOrderList = order.getChildOrderList(true);
            ChildOrder childOrder = childOrderList.get(0);

            childOrder.setPaymentStatus(OrderConstant.PaymentStatus.SUCCESS);
            childOrder.setTransactionStatus(OrderConstant.TransactionStatus.WAIT_RECEIPT);
            childOrder.setShipStatus(OrderConstant.ShipStatus.ALREADY_SHIP);
            childOrder.setReceiptStatus(OrderConstant.ReceiptStatus.NO);
            childOrder.setEnd(false);


            /**
             * 使用完成之后开始自动评价
             SaleConfig config = saleConfigService.getConfig();
             Integer  autoCommentProcessDays = 7;
             if(config!=null)
             {
             autoCommentProcessDays = config.getAutoCommentProcessDays();
             }
             childOrder.setLastCommentTime(OrderConstant.getTomorrowAndDayTimestamp(System.currentTimeMillis(),autoCommentProcessDays));
             childOrder.setLastEndTime(OrderConstant.getTomorrowAndDayTimestamp(System.currentTimeMillis(), childOrder.getValidity()));
             **/
            childOrderService.modify(childOrder);

            SaleServiceGoodsCard saleServiceGoodsCard = childOrder.loadServiceCard();
            saleServiceGoodsCard.setExpiredUseTime(OrderConstant.getTomorrowAndDayTimestamp(System.currentTimeMillis(), saleServiceGoodsCard.getValidity()));
            saleServiceGoodsCardService.modify(saleServiceGoodsCard);

            ServiceGoods goods = serviceGoodsService.loadServiceGoodsById(childOrder.getGoodsId(), false);
            goods.incSaleNum(childOrder.getNumber());
            serviceGoodsService.modify(goods);

            //计算商家与会员分润所得
            if ((!order.getExchange()) && order.getTotalAmount().compareTo(BigDecimal.ZERO) > 0) {
                shopOrderGainsService.initCreate(order);
            }
        });

        return payOrder;
    }

    private PayOrder serviceGoodsPayFailSuccess(PayOrder payOrder) {

        List<Order> orders = orderService.loadByPayOrderId(payOrder.getId());
        orders.forEach(order -> {
            //主订单
            order.setTransactionStatus(OrderConstant.TransactionStatus.CLOSE);
            order.setPaymentStatus(OrderConstant.PaymentStatus.FAIL);
            order.setShipStatus(OrderConstant.ShipStatus.NO_SHIP);
            order.setReceiptStatus(OrderConstant.ReceiptStatus.NO);
            order.setPayTime(payOrder.getPayTime());
            order.setPayMode(payOrder.getPayMode());
            order.setCloseTime(payOrder.getCloseTime());
            order.setEnd(true);
            order.setCloseMode(OrderConstant.CloseMode.THIRD_PAY_FAIL);
            orderService.modify(order);
            /**
             * 更主业务订单订单中的所有子订单的状态
             */
            List<ChildOrder> childOrderList = order.getChildOrderList(true);
            ChildOrder childOrder = childOrderList.get(0);

            childOrder.setPaymentStatus(OrderConstant.PaymentStatus.FAIL);
            childOrder.setTransactionStatus(OrderConstant.TransactionStatus.CLOSE);
            childOrder.setShipStatus(OrderConstant.ShipStatus.NO_SHIP);
            childOrder.setReceiptStatus(OrderConstant.ReceiptStatus.NO);
            childOrder.setEnd(true);
            childOrderService.modify(childOrder);

        });

        return payOrder;
    }

    /**
     * 订单取消支付回退库存
     *
     * @param childOrder
     */
    private void processSingleGoodsStock(ChildOrder childOrder, GoodsConstant.InStockType inStockType) {
        OrderStockTo orderStockTo = new OrderStockTo();
        orderStockTo.setChangeStock(childOrder.getNumber());
        orderStockTo.setChildReferId(childOrder.getId());
        orderStockTo.setGoodsTitle(childOrder.getGoodsTitle());
        orderStockTo.setOrderCode(childOrder.getOrderCode());
        orderStockTo.setOrderId(childOrder.getOrderId());
        orderStockTo.setSingleGoodsId(childOrder.getSingleGoodsId());
        orderStockTo.setSkuSetName(childOrder.getSkuSetName());
        orderStockTo.setUserMobile(childOrder.getMobile());
        productSingleGoodsService.cancelPayInStock(childOrder.getShopId(), orderStockTo, inStockType);
    }


    /**
     * 内部调用取消支付订单
     *
     * @param payOrder
     * @param closeMode
     * @param inStockType
     * @return
     */
    private PayOrder cancel(PayOrder payOrder, OrderConstant.CloseMode closeMode, GoodsConstant.InStockType inStockType) {
        //支付订单关单
        payOrder.setClose(true);
        payOrder.setCloseMode(closeMode);
        payOrder.setCloseTime(System.currentTimeMillis());

        payOrderService.modify(payOrder);

        List<Order> orders = orderService.loadByPayOrderId(payOrder.getId());
        orders.forEach(order -> {
            //主订单关单
            order.setEnd(true);
            order.setCloseMode(closeMode);
            order.setCloseTime(payOrder.getCloseTime());
            order.setTransactionStatus(OrderConstant.TransactionStatus.CLOSE);
            if (OrderConstant.CloseMode.PAY_EXPIRE.equals(closeMode)) {
                order.setPaymentStatus(OrderConstant.PaymentStatus.EXPIRE);
                order.setExpired(true);
            }
            orderService.modify(order);

            List<ChildOrder> childOrderList = order.getChildOrderList(true);
            //子订单关单
            childOrderList.forEach(child -> {
                child.setEnd(true);
                child.setTransactionStatus(OrderConstant.TransactionStatus.CLOSE);
                if (OrderConstant.CloseMode.PAY_EXPIRE.equals(closeMode)) {
                    child.setPaymentStatus(OrderConstant.PaymentStatus.EXPIRE);
                }
                childOrderService.modify(child);
            });

            if (OrderConstant.OrderType.SALE_ORDER.equals(order.getOrderType())) {

                childOrderList.sort(Comparator.comparing(ChildOrder::getSingleGoodsId));
                //订单取消支付回退库存
                for (ChildOrder child : childOrderList) {
                    processSingleGoodsStock(child, inStockType);
                }

                //如果是拼团这里也需要处理回退
                if (order.getMarketingType() == 2) {
                    groupBuyTeamMemberService.memberPayExpireHandler(order);
                }

                //如果是秒杀这里也需要处理回退
                if (order.getMarketingType() == 1) {
                    seckillActivityGoodsService.payExpireHandler(order);
                }

                if (order.getTotalPoint().compareTo(BigDecimal.ZERO) > 0) {
                    switch (closeMode) {
                        case PAY_EXPIRE:
                            integralRecordService.inner(new IntegralRecord(order.getUserId(), order.getTotalPoint(),
                                    IntegralConstant.InnerMode.PAY_EXPIRE, IntegralConstant.IntegralModelType.ORDER, order.getId(),
                                    String.format("订单[%s]支付期退还积分:%.2f", order.getOrderCode(), order.getTotalPoint())));
                            break;
                        case USER_CANCEL:
                            integralRecordService.inner(new IntegralRecord(order.getUserId(), order.getTotalPoint(),
                                    IntegralConstant.InnerMode.CANCEL_ORDER, IntegralConstant.IntegralModelType.ORDER, order.getId(),
                                    String.format("取消订单[%s]退还积分:%.2f", order.getOrderCode(), order.getTotalPoint())));
                            break;
                    }

                }
            }
        });

        return payOrder;
    }

}
